package com.cloudfun.campusshare.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.cloudfun.campusshare.common.constant.*;
import com.cloudfun.campusshare.common.exception.BusinessException;
import com.cloudfun.campusshare.common.model.MerchantAccountDTO;
import com.cloudfun.campusshare.common.model.dto.KjtSubMerchantDTO;
import com.cloudfun.campusshare.common.model.dto.kjt.*;
import com.cloudfun.campusshare.common.model.vo.KjtSubMerchantVO;
import com.cloudfun.campusshare.common.security.AuthenticationHolder;
import com.cloudfun.campusshare.entity.SubMerchantEntity;
import com.cloudfun.campusshare.repo.KjtSubMerchantRepo;
import com.cloudfun.campusshare.service.KjtService;
import com.cloudfun.campusshare.service.KjtSubMerchantService;
import com.cloudfun.campusshare.service.MerchantAccountService;
import com.cloudfun.campusshare.util.AmountUtil;
import com.cloudfun.campusshare.util.BeanCopyUtil;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;

/**
 * Created by CodeGenerator on 2020/08/10
 */
@Slf4j
@Service
public class KjtSubMerchantServiceImpl implements KjtSubMerchantService {

    @Autowired
    private KjtSubMerchantRepo kjtSubMerchantRepo;

    @Autowired
    private KjtService kjtService;

    @Override
    @Transactional
    public String createSubMerchantPage(String userId) {
        Optional<SubMerchantEntity> subMerchantEntityOpt = kjtSubMerchantRepo.findByUserId(userId);
        SubMerchantEntity subMerchantEntity;
        KjtSubMerchantRegPageReqDTO dto = new KjtSubMerchantRegPageReqDTO();
        if (subMerchantEntityOpt.isPresent()) {
            subMerchantEntity = subMerchantEntityOpt.get();
            if (KjtAuditStatus.S == subMerchantEntity.getAuditStatus()) {
                throw new BusinessException(Code.DATA_EXIST, "用户已注册子商户");
            }
        } else {
            subMerchantEntity = new SubMerchantEntity();
            subMerchantEntity.setUserId(userId);
            subMerchantEntity.setOpeningStatus(KjtAuditStatus.P);
            subMerchantEntity = kjtSubMerchantRepo.save(subMerchantEntity);
        }
        dto.setPartnerUserId(subMerchantEntity.getId());
        return kjtService.subMerchantRegisterPage(dto).getUrl();
    }

    public void createSubMerchant(KjtSubMerchantCreateDTO createDTO) {
        Optional<SubMerchantEntity> subMerchantEntityOpt = kjtSubMerchantRepo.findByUserId(AuthenticationHolder.getUserId());
        if (subMerchantEntityOpt.isPresent()) {
            throw new BusinessException(Code.DATA_EXIST, "用户已注册子商户");
        }
        subMerchantEntityOpt = kjtSubMerchantRepo.findByEmail(createDTO.getEmail());
        if (subMerchantEntityOpt.isPresent()) {
            throw new BusinessException(Code.DATA_EXIST, "邮箱已注册子商户");
        }
        SubMerchantEntity subMerchantEntity = new SubMerchantEntity();
        BeanUtil.copyProperties(createDTO, subMerchantEntity, "entrustWithdrawalAmount");
        subMerchantEntity.setUserId(AuthenticationHolder.getUserId());
        subMerchantEntity.setOpeningStatus(KjtAuditStatus.P);
        subMerchantEntity.setAuditStatus(KjtAuditStatus.P);
        if (SettleType.ENTRUST_WITHDRAWAL == subMerchantEntity.getSettleType()) {
            subMerchantEntity.setEntrustWithdrawalAmount(AmountUtil.strAmount2Int(createDTO.getEntrustWithdrawalAmount()));
        }
        kjtSubMerchantRepo.save(subMerchantEntity);
        String subMerchantId = subMerchantEntity.getId();
        createDTO.setId(subMerchantId);
        KjtSubMerchantRegReqDTO regReqDTO = this.buildRegDTO(createDTO);
        KjtSubMerchantRegRespDTO subMerchantRegRespDTO = kjtService.subMerchantRegister(regReqDTO);
        this.handleRegResponse(subMerchantRegRespDTO);
    }

    @Override
    @Transactional
    public void handleRegResponse(KjtSubMerchantRegRespDTO subMerchantRegRespDTO) {
        String subMerchantId = subMerchantRegRespDTO.getPartnerUserId();
        SubMerchantEntity subMerchantEntity = kjtSubMerchantRepo.findById(subMerchantId).orElseThrow(() -> new BusinessException(Code.NODATA));
        subMerchantEntity.setIdentityId(subMerchantRegRespDTO.getIdentityId());
        subMerchantEntity.setOpeningStatus(subMerchantRegRespDTO.getOpeningStatus());
        subMerchantEntity.setFailReason(subMerchantRegRespDTO.getFailReason());
        subMerchantEntity.setAuditStatus(subMerchantRegRespDTO.getAuditStatus());
        subMerchantEntity.setRejectReason(subMerchantRegRespDTO.getRejectedReason());
        if (KjtAuditStatus.S != subMerchantEntity.getOpeningStatus() && KjtAuditStatus.S == subMerchantEntity.getAuditStatus()) {
            //查询快捷通补充商户资料
            KjtQuerySubMerchantBankCardInfoReqDTO reqDTO = KjtQuerySubMerchantBankCardInfoReqDTO.builder()
                    .identityId(subMerchantEntity.getIdentityId())
                    .build();
            KjtQuerySubMerchantBankCardInfoRespDTO respDTO = kjtService.querySubMerchantBankCardInfo(reqDTO);
            if (BankType.searchValue(respDTO.getCompanyOrPerson())!=null){
                subMerchantEntity.setCompanyOrPerson(BankType.searchValue(respDTO.getCompanyOrPerson()));
            }
        }
        kjtSubMerchantRepo.save(subMerchantEntity);
    }

    @Override
    @Transactional
    public void resubmission(KjtSubMerchantResubmissionDTO resubmissionDTO) {
        SubMerchantEntity subMerchantEntity = kjtSubMerchantRepo.findByUserId(AuthenticationHolder.getUserId()).orElseThrow(() -> new BusinessException(Code.NODATA));
        if (KjtAuditStatus.P == subMerchantEntity.getAuditStatus()) {
            throw new BusinessException(Code.ERROR, "审核中不能重提");
        }
        if (KjtAuditStatus.S == subMerchantEntity.getAuditStatus()) {
            throw new BusinessException(Code.ERROR, "已通过不能重提");
        }
        String subMerchantId = subMerchantEntity.getId();
        if (subMerchantEntity.getThreeCertFlag() != resubmissionDTO.getThreeCertFlag()) {
            if (!subMerchantEntity.getThreeCertFlag() && resubmissionDTO.getThreeCertFlag()) {
                // 以前不是三证合一，现在是三证合一，删除掉组织机构代码证影印件和税务登记影印件
                kjtService.deletePhotoCopy(subMerchantId, AttachType.TAX_PHOTO);
                kjtService.deletePhotoCopy(subMerchantId, AttachType.ORGANIZATION_NUMBER_PHOTO);
            }
        }
        if (subMerchantEntity.getShopType() != resubmissionDTO.getShopType()) {
            // 以前是网店，现在是门店
            if (ShopType.ONLINE_SHOP == subMerchantEntity.getShopType() && ShopType.STORE == resubmissionDTO.getShopType()) {
                kjtService.deletePhotoCopy(subMerchantId, AttachType.ONLINE_SHOP_PHOTO);
            }
            // 以前是门店，现在是网店
            if (ShopType.STORE == subMerchantEntity.getShopType() && ShopType.ONLINE_SHOP == resubmissionDTO.getShopType()) {
                kjtService.deletePhotoCopy(subMerchantId, AttachType.STORE_PHOTO);
            }
        }
        subMerchantEntity.setCustomerType(resubmissionDTO.getCustomerType());
        subMerchantEntity.setCertificatesValidity(resubmissionDTO.getCertificatesValidity());
        subMerchantEntity.setShopType(resubmissionDTO.getShopType());
        kjtSubMerchantRepo.save(subMerchantEntity);

        KjtResubmissionInfoDTO infoDTO = new KjtResubmissionInfoDTO();
        BeanUtil.copyProperties(resubmissionDTO, infoDTO);
        infoDTO.setPartnerUserId(subMerchantId);
        infoDTO.setIdentityId(subMerchantEntity.getIdentityId());
        infoDTO.setCustomerType(resubmissionDTO.getCustomerType().getCode());
        infoDTO.setShopType(resubmissionDTO.getShopType().getValue());
        KjtSubMerchantCreateDTO createDTO = new KjtSubMerchantCreateDTO();
        BeanUtil.copyProperties(resubmissionDTO, createDTO);
        infoDTO.setPhotoCopyMap(this.buildPhotoCopyDTO(createDTO));
        infoDTO.setCompanyProperty(this.buildSubMerchantRegExtDTO(createDTO));
        KjtResubmissionInfoRespDTO kjtResubmissionInfoRespDTO = kjtService.resubmissionInformation(infoDTO);
        this.handleRegResponse(kjtResubmissionInfoRespDTO);
    }

    @Override
    public KjtSubMerchantVO getByEmail(String email) {
        SubMerchantEntity merchantEntity = kjtSubMerchantRepo.findByEmail(email).orElseThrow(() -> new BusinessException(Code.NODATA));
        return BeanCopyUtil.copy(merchantEntity, KjtSubMerchantVO.class);
    }

    @Override
    public KjtSubMerchantDTO regQuery() {
        SubMerchantEntity subMerchantEntity = kjtSubMerchantRepo.findByUserId(AuthenticationHolder.getUserId()).orElseThrow(() -> new BusinessException(Code.NODATA));
        KjtSubMerchantRegQueryDTO queryDTO = new KjtSubMerchantRegQueryDTO();
        queryDTO.setPartnerUserId(subMerchantEntity.getId());
        KjtSubMerchantRegQueryRespDTO queryRespDTO = kjtService.subMerchantRegisteredQuery(queryDTO);
        this.handleRegResponse(queryRespDTO);
        return BeanCopyUtil.copy(kjtSubMerchantRepo.findByUserId(AuthenticationHolder.getUserId()).get(), KjtSubMerchantDTO.class);
    }

    @Override
    public Optional<SubMerchantEntity> getEntityById(String id) {
        return kjtSubMerchantRepo.findById(id);
    }

    @Override
    public Optional<SubMerchantEntity> getEntityByUserId(String userId) {
        return kjtSubMerchantRepo.findByUserId(userId);
    }

    @Override
    public Optional<SubMerchantEntity> getEntityByIdentityId(String identityId) {
        return kjtSubMerchantRepo.findByIdentityId(identityId);
    }

    @Override
    public List<SubMerchantEntity> getEntities() {
        return Lists.newArrayList(kjtSubMerchantRepo.findAll());
    }

    @Override
    public void save(SubMerchantEntity subMerchantEntity) {
        kjtSubMerchantRepo.save(subMerchantEntity);
    }

    /**
     * 构造子商户注册对象
     *
     * @param createDTO
     * @return
     */
    private KjtSubMerchantRegReqDTO buildRegDTO(KjtSubMerchantCreateDTO createDTO) {
        KjtSubMerchantRegReqDTO regDTO = new KjtSubMerchantRegReqDTO();
        BeanUtil.copyProperties(createDTO, regDTO, "customerType", "certificatesValidity", "companyOrPerson", "shopType", "settleType");
        regDTO.setPartnerUserId(createDTO.getId());
        regDTO.setCustomerType(createDTO.getCustomerType().getCode());
        regDTO.setCertificatesValidity(KjtSubMerchantRegReqDTO.CERTIFICATES_VALIDITY_FORMATTER.format(createDTO.getCertificatesValidity()));
        regDTO.setCompanyOrPerson(createDTO.getCompanyOrPerson().getValue());
        regDTO.setShopType(createDTO.getShopType().getValue());
        regDTO.setSettleType(createDTO.getSettleType().getValue());
        regDTO.setPhotoCopyMap(this.buildPhotoCopyDTO(createDTO));
        regDTO.setCompanyProperty(this.buildSubMerchantRegExtDTO(createDTO));
        regDTO.setNotifyUrl("");//TODO
        return regDTO;
    }

    /**
     * 构造企业、个体工商户扩展信息
     *
     * @param createDTO
     * @return
     */
    private KjtEnterpriseRegExtDTO buildSubMerchantRegExtDTO(KjtSubMerchantCreateDTO createDTO) {
        KjtEnterpriseRegExtDTO regExtDTO = new KjtEnterpriseRegExtDTO();
        BeanUtil.copyProperties(createDTO, regExtDTO, "businessLicenseValidity", "threeCertFlag");
        regExtDTO.setBusinessLicenseValidity(KjtSubMerchantRegExtBaseDTO.BUSINESS_LICENSE_VALIDITY_FORMATTER.format(createDTO.getBusinessLicenseValidity()));
        regExtDTO.setThreeCertFlag(BooleanUtils.isTrue(createDTO.getThreeCertFlag()) ? "1" : "0");
        return regExtDTO;
    }

    /**
     * 构造影印件对象
     *
     * @param createDTO
     * @return
     */
    private KjtPhotoCopyBaseDTO buildPhotoCopyDTO(KjtSubMerchantCreateDTO createDTO) {
        KjtEnterprisePhotoCopyDTO photoCopyDTO = new KjtEnterprisePhotoCopyDTO();
        String certificatesFrontUrl = kjtService.uploadPhotoCopy(createDTO.getCertificatesFrontId(), createDTO.getId(), AttachType.ID_CARD_FRONT);
        photoCopyDTO.setCertificatesFront(certificatesFrontUrl);

        String certificatesBackUrl = kjtService.uploadPhotoCopy(createDTO.getCertificatesBackId(), createDTO.getId(), AttachType.ID_CARD_BACK);
        photoCopyDTO.setCertificatesBack(certificatesBackUrl);

        if (StringUtils.isNotBlank(createDTO.getNetworkUrlPhotoId())) {
            String networkUrlPhotoUrl = kjtService.uploadPhotoCopy(createDTO.getNetworkUrlPhotoId(), createDTO.getId(), AttachType.ONLINE_SHOP_PHOTO);
            photoCopyDTO.setNetworkUrlPhoto(networkUrlPhotoUrl);
        } else {
            String storeUrls = String.join(",", kjtService.uploadPhotoCopy(createDTO.getStoreIds(), createDTO.getId(), AttachType.STORE_PHOTO));
            photoCopyDTO.setStore(storeUrls);
        }

        String businessLeaseContractUrls = String.join(",", kjtService.uploadPhotoCopy(createDTO.getBusinessLeaseContractIds(), createDTO.getId(), AttachType.BUSINESS_LEASE_CONTRACT));
        photoCopyDTO.setBusinessLeaseContract(businessLeaseContractUrls);

        String licenseUrl = kjtService.uploadPhotoCopy(createDTO.getLicenseId(), createDTO.getId(), AttachType.LICENSE);
        photoCopyDTO.setLicense(licenseUrl);

        String openLicenseUrl = kjtService.uploadPhotoCopy(createDTO.getOpenLicenseId(), createDTO.getId(), AttachType.OPEN_LICENSE);
        photoCopyDTO.setOpenLicense(openLicenseUrl);

        if (StringUtils.isNotBlank(createDTO.getOrganizationNumberId())) {
            String organizationNumberUrl = kjtService.uploadPhotoCopy(createDTO.getOrganizationNumberId(), createDTO.getId(), AttachType.ORGANIZATION_NUMBER_PHOTO);
            photoCopyDTO.setOrganizationNumber(organizationNumberUrl);
        }
        if (StringUtils.isNotBlank(createDTO.getTaxId())) {
            String taxUrl = kjtService.uploadPhotoCopy(createDTO.getTaxId(), createDTO.getId(), AttachType.OPEN_LICENSE);
            photoCopyDTO.setTax(taxUrl);
        }
        return photoCopyDTO;
    }
}